<!--
 * @Description: 表单表格
-->
<template>
  <div class="my-form-table" ref="formTableRef">
    <el-table :data="data" ref="tableRef" border stripe>
      <el-table-column type="index" width="50" fixed="left">
        <template #header>
          <el-button
            v-if="!props.hideAdd"
            type="primary"
            icon="el-icon-plus"
            size="small"
            circle
            @click="onCreate"
          ></el-button>
        </template>
        <template #default="scope">
          <div :class="['my-form-table-handle', { 'my-form-table-handle-delete': !hideDelete }]">
            <span>{{ scope.$index + 1 }}</span>
            <el-button
              v-if="!hideDelete"
              type="danger"
              icon="el-icon-delete"
              size="small"
              plain
              circle
              @click="onDelete(scope.$index)"
            ></el-button>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="" width="50" v-if="dragSort">
        <template #default>
          <div class="move" style="cursor: move"><el-icon-d-caret style="width: 1em; height: 1em" /></div>
        </template>
      </el-table-column>
      <slot></slot>
      <template #empty>
        {{ placeholder }}
      </template>
    </el-table>
  </div>
</template>

<script setup lang="ts" name="formTable">
import { ElTable } from 'element-plus'
import Sortable from 'sortablejs'
import { ref, onMounted, watch, nextTick } from 'vue'
import { ComponentPublicInstance } from 'vue/dist/vue.js'

interface IProps {
  modelValue: string[]
  addTemplate: Object
  placeholder: string
  dragSort?: boolean
  hideCreate?: boolean
  hideDelete?: boolean
}
const props = withDefaults(defineProps<IProps>(), {
  modelValue: Array,
  addTemplate: Object,
  placeholder: '暂无数据',
  dragSort: false,
  hideAdd: false,
  hideDelete: false
})

const data = ref()
const formTableRef = ref<ComponentPublicInstance | null>(null)
const tableRef = ref<InstanceType<typeof ElTable> | null>(null)

watch(
  () => props.modelValue,
  () => (data.value = props.modelValue)
)
onMounted(() => {
  data.value = props.modelValue
  if (props.dragSort) rowDrop()
})

const rowDrop = () => {
  const tbody = tableRef.value?.$el.querySelector('.el-table__body-wrapper tbody')
  Sortable.create(tbody, {
    handle: '.move',
    animation: 300,
    ghostClass: 'ghost',
    onEnd({ newIndex, oldIndex }) {
      data.value.splice(newIndex, 0, data.value.splice(oldIndex, 1)[0])
      const newArray = data.value.slice(0)
      const tmpHeight = formTableRef.value?.$el.offsetHeight
      formTableRef.value?.$el.style.setProperty('height', tmpHeight + 'px')
      data.value = []
      nextTick(() => {
        data.value = newArray
        nextTick(() => formTableRef.value?.$el.style.removeProperty('height'))
      })
    }
  })
}

// 插入行
const onCreate = () => {
  const temp = JSON.parse(JSON.stringify(props.addTemplate))
  data.value.push(temp)
}

// 删除
const onDelete = (index: number) => data.value.splice(index, 1)
</script>

<style scoped lang="scss">
.my-form-table {
  width: 100%;
  .my-form-table-handle {
    text-align: center;
    span {
      display: inline-block;
    }
    button {
      display: none;
    }
  }
  .hover-row {
    .my-form-table-handle-delete {
      span {
        display: none;
      }
      button {
        display: inline-block;
      }
    }
  }
  .move {
    text-align: center;
    font-size: 14px;
    margin-top: 3px;
  }
}
</style>
